package com.itheima.mapper;

import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.util.List;

@Mapper
public interface EmpMapper {

    // 删除数据库中的数据  使用mybatis中提供的参数占位符 #{} 可以获取方法中传输的参数
    @Delete("delete from emp where id = #{id}")
    public void delete(Integer id);
    // 这个方法其实是有返回值的，返回的是操作数据的条数，所以返回值类型可以写成int

    // 向数据库中添加数据  同样使用#{}的形式传输参数
    // 有多个参数对象时方法传输的数据可以是emp对象 则#{}中的值就是对应的属性

    // 当我们需要获得当前添加数据的主键值时（即增加完数据后我们需要使用getID()方法获得主键）
    // 我们可以在@Insert注解前面添加一个@Options注解
    // 该注解需要两个值 useGeneratedKeys = true 表示需要获取当前数据的主键值
    // keyProperty = "id" 表示将获取的主键值赋值给emp中的id属性
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            " values(#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime}) ")
    public void insert(Emp emp);

    // 更新数据库中的数据
    @Update("update emp set username = #{username}, name = #{name}, image = #{image}, gender = #{gender}, " +
            "job = #{job}, entrydate = #{entrydate}, update_time = #{updateTime} where id = #{id}")
    public void update(Emp emp);

    // 根据id查询数据库中的数据
//    @Select("select * from emp where id = #{id}")
//    public Emp getById(Integer id);

    // 使用上述查询方式会出现一些问题 因为数据库中的列名与实体类中的属性名不同（数据库中采用的是用_连接两个单词 实体类中采用的是驼峰命名法）
    // 方案一：给字段起别名，让别名与实体类与属性一致
//    @Select("select id, username, password, name, gender, image, job, entrydate," +
//            " dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
//    public Emp getById(Integer id);

    // 方案二；通过@Results,@Result注解手动映射封装
    // @Results注解中填写的值是一个@Result数组
    // @Result注解中填写需要映射的列名和属性名
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getById(Integer id);

    // 方案三：开启mybatis中的驼峰命名自动映射开
    // mybatis提供了自动将 _ 命名的规则映射为 驼峰命名的开关
    // 直接在resources文件夹中的application文件中添加一行代码 mybatis.configuration.map-underscore-to-camel-case=true 即可
    @Select("select * from emp where id = #{id}")
    public Emp getById(Integer id);

    // 完成案例 在数据库中查询出与给定信息相匹配的数据
    // 查询出 姓名中有 张 性别是 男 入职时间是 2010-01-01 到 2020-01-01 之间的
    // 此时使用List集合接收查询的数据 因为查询的数据可以有很多条
    // 这里使用了一个字符串的拼接方法concat()，是因为在字符串中不能使用#{}的形式
    // （其实可以使用${}的形式只是不是预编译的SQL存在SQL注入的问题）
//    @Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} " +
//            "and entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin,@Param("end") LocalDate end);
    // 此处一定要注意使用 Short 引用数据类型 写short会报错


    // 使用XML文件实现mybatis使用sql语句 查询数据（使用动态sql 可以灵活的进行查询）
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
    public List<Emp> list(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);



    // 使用XML文件实现 修改数据（使用动态sql 可以灵活的进行修改）
    public void update2(Emp emp);

    // 批量删除数据 删除id为 18 20 21
    public void deleteById(@Param("ids") List<Integer> ids);

}
